package cn.iocoder.yudao.module.wms.service.customerclassify;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.wms.controller.admin.customerclassify.vo.CustomerClassifyPageReqVO;
import cn.iocoder.yudao.module.wms.controller.admin.customerclassify.vo.CustomerClassifySaveReqVO;
import cn.iocoder.yudao.module.wms.dal.dataobject.customer.CustomerDO;
import cn.iocoder.yudao.module.wms.dal.dataobject.customerclassify.CustomerClassifyDO;
import cn.iocoder.yudao.module.wms.dal.mysql.customer.CustomerMapper;
import cn.iocoder.yudao.module.wms.dal.mysql.customerclassify.CustomerClassifyMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.*;

/**
 * 客户分类 Service 实现类
 *
 * @author 曾劲松
 */
@Service
@Validated
public class CustomerClassifyServiceImpl implements CustomerClassifyService {

    @Resource
    private CustomerClassifyMapper customerClassifyMapper;

    @Resource
    private CustomerMapper customerMapper;

    @Override
    public Long createCustomerClassify(CustomerClassifySaveReqVO createReqVO) {
        validateCodeOrNameExists(createReqVO);
        // 插入
        CustomerClassifyDO customerClassify = BeanUtils.toBean(createReqVO, CustomerClassifyDO.class);
        customerClassifyMapper.insert(customerClassify);
        // 返回
        return customerClassify.getId();
    }

    @Override
    public void updateCustomerClassify(CustomerClassifySaveReqVO updateReqVO) {
        // 校验存在
        validateCustomerClassifyExists(updateReqVO.getId());
        validateCodeOrNameExists(updateReqVO);
        // 更新
        CustomerClassifyDO updateObj = BeanUtils.toBean(updateReqVO, CustomerClassifyDO.class);
        customerClassifyMapper.updateById(updateObj);
    }

    @Override
    public void deleteCustomerClassify(Long id) {
        // 校验存在
        validateCustomerClassifyExists(id);
        // 校验是否有子分类
        if (customerClassifyMapper.selectCount(CustomerClassifyDO::getParentId, id) > 0) {
            throw exception(CUSTOMER_CLASSIFY_EXITS_CHILDREN);
        }
        // 校验分类下是否有客户
        if (customerMapper.selectCount(CustomerDO::getClassifyId, id) > 0) {
            throw exception(CUSTOMER_CLASSIFY_EXITS_CUSTOMER);
        }
        // 删除
        customerClassifyMapper.deleteById(id);
    }

    /**
     * 校验客户分类是否存在
     * @param id 客户分类id
     */
    private void validateCustomerClassifyExists(Long id) {
        if (customerClassifyMapper.selectById(id) == null) {
            throw exception(CUSTOMER_CLASSIFY_NOT_EXISTS);
        }
    }

    /**
     * 校验编码或名称是否存在
     * @param reqVO 客户分类Request VO
     */
    private void validateCodeOrNameExists(CustomerClassifySaveReqVO reqVO) {
        if (customerClassifyMapper.selectCount(CustomerClassifyDO::getCode, reqVO.getCode()) > 0) {
            throw exception(CUSTOMER_CLASSIFY_CODE_EXISTS);
        }
        if (customerClassifyMapper.selectCount(CustomerClassifyDO::getName, reqVO.getName()) > 0) {
            throw exception(CUSTOMER_CLASSIFY_NAME_EXISTS);
        }
    }

    @Override
    public CustomerClassifyDO getCustomerClassify(Long id) {
        return customerClassifyMapper.selectById(id);
    }

    @Override
    public PageResult<CustomerClassifyDO> getCustomerClassifyPage(CustomerClassifyPageReqVO pageReqVO) {
        return customerClassifyMapper.selectPage(pageReqVO, getClassifyCondition(pageReqVO.getParentId()));
    }

    @Override
    public List<CustomerClassifyDO> getCustomerClassifyList() {
        return customerClassifyMapper.selectList();
    }

    @Override
    public List<CustomerClassifyDO> getChildCustomerClassifyList(Collection<Long> ids) {
        List<CustomerClassifyDO> children = new LinkedList<>();
        // 遍历每一层
        Collection<Long> parentIds = ids;
        for (int i = 0; i < Short.MAX_VALUE; i++) {
            List<CustomerClassifyDO> classifys = customerClassifyMapper.selectList(CustomerClassifyDO::getParentId, parentIds);
            if (CollUtil.isEmpty(classifys)) {
                break;
            }
            children.addAll(classifys);
            parentIds = convertSet(classifys, CustomerClassifyDO::getId);
        }
        return children;
    }

    /**
     * 获得客户分类条件：查询指定客户分类的子分类编号们，包括自身
     *
     * @param classifyId 客户分类编号
     * @return 客户分类编号集合
     */
    private Set<Long> getClassifyCondition(Long classifyId) {
        if (classifyId == null) {
            return Collections.emptySet();
        }
        Set<Long> classifyIds = convertSet(getChildCustomerClassifyList(Collections.singleton(classifyId)), CustomerClassifyDO::getId);
        classifyIds.add(classifyId); // 包括自身
        return classifyIds;
    }

}